package com.changgou.oauth.service.impl;

import java.util.Base64;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.changgou.oauth.service.LoginService;
import com.changgou.oauth.util.AuthToken;

@Service("loginServiceImpl")
public class LoginServiceImpl implements LoginService {
    @Resource
    private RestTemplate restTemplate;

    @Resource
    private LoadBalancerClient loadBalancerClient;

    @Override
    public AuthToken login(String username, String password, String clientId, String clientSecret, String grandType) {
        // 1.定义url (申请令牌的url)
        // 参数 : 微服务的名称spring.application指定的名称
        ServiceInstance choose = loadBalancerClient.choose("user-auth");
        String url = choose.getUri().toString() + "/oauth/token";

        // 2.定义头信息 (有client id 和client secret)
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Authorization",
            "Basic " + Base64.getEncoder().encodeToString((clientId + ":" + clientSecret).getBytes()));

        // 3. 定义请求体 有授权模式 用户的名称 和密码
        MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
        formData.add("grant_type", grandType);
        formData.add("username", username);
        formData.add("password", password);
        // 4.模拟浏览器 发送POST 请求 携带 头 和请求体 到认证服务器

        /**
         * 参数1 指定要发送的请求的url 参数2 指定要发送的请求的方法 PSOT 参数3 指定请求实体(包含头和请求体数据)
         */
        HttpEntity<MultiValueMap> requestEntity = new HttpEntity<>(formData, headers);

        ResponseEntity<Map> responseEntity;
        try {
            responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class);
        } catch (RestClientException e) {
            return null;
        }

        // 5.接收到返回的响应(就是:令牌的信息)
        Map<String, String> body = responseEntity.getBody();

        // 封装一次.
        AuthToken authToken = new AuthToken();
        String accessToken = body.get("access_token");
        String refreshToken = body.get("refresh_token");
        String jwtToken = body.get("jti");

        authToken.setJti(jwtToken);
        authToken.setAccessToken(accessToken);
        authToken.setRefreshToken(refreshToken);

        // 6.返回
        return authToken;
    }
}